package io.hummer.prefetch.ws;
import io.hummer.prefetch.impl.PrefetchingServiceImpl;
import java.util.HashMap;
import java.util.Map;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.annotation.adapters.XmlAdapter;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.transform.dom.DOMResult;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
/**
* Custom JAXB (un-)marshaller required to hold abstract
* parameter types in some Web service interfaces.
*
* @author Waldemar Hummer (hummer@dsg.tuwien.ac.at)
*/
public class JaxbAdapter extends XmlAdapter<Object,Object> {
//private static final XMLUtil xmlUtil = new XMLUtil();
private static final Map<Class<?>,JAXBContext> contexts = new HashMap<>();
public Object marshal(Object o) throws Exception {
if(o == null) {
return null;
}
if(o instanceof SOAPEnvelope) {
return WSClient.toElement(
WSClient.toString((SOAPEnvelope)o));
}
Class<?> clazz = o.getClass();
if(!contexts.containsKey(clazz)) {
JAXBContext c = JAXBContext.newInstance(clazz);
contexts.put(clazz, c);
}
JAXBContext c = contexts.get(clazz);
DOMResult res = new DOMResult();
c.createMarshaller().marshal(o, res);
Element e = ((Document)res.getNode()).getDocumentElement();
e.setAttribute("class", clazz.getCanonicalName());
return e;
}
public Object unmarshal(Object o) throws Exception {
Element e = (Element)o;
String name = e.getLocalName();
if(name.equalsIgnoreCase("Envelope")) {
return WSClient.toEnvelope((Element)o);
} else {
Class<?> clazz = PrefetchingServiceImpl.class;
String className = e.getAttribute("class");
if(!className.isEmpty()) {
clazz = Class.forName(className);
}
if(!contexts.containsKey(clazz)) {
JAXBContext c = JAXBContext.newInstance(clazz);
contexts.put(clazz, c);
}
JAXBContext c = contexts.get(clazz);
Object res = c.createUnmarshaller().unmarshal(e);
return res;
}
}
}